package cn.js.sangu.unitStore.service;

import cn.hutool.core.date.DateUtil;
import cn.js.sangu.unitStore.dto.*;
import cn.js.sangu.unitStore.entity.Charts;
import cn.js.sangu.unitStore.entity.User;
import cn.js.sangu.unitStore.mapper.ChartsMapper;
import cn.js.sangu.unitStore.mapper.UserMapper;
import cn.js.sangu.unitStore.utils.DTOConverter;
import cn.js.sangu.unitStore.utils.LinsUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 说明：图表统计服务
 * 作者：linshuo
 */
@Slf4j
@Service
public class ChartsService extends ServiceImpl<ChartsMapper, Charts> {

    @Autowired
    ChartsMapper chartsMapper;

    @Autowired
    UserService userService;

    @Resource
    UserMapper userMapper;

//    public boolean refresh(String lineText,String barText,String pieText){
//        Charts charts = new Charts();
//        charts.setLine(new ObjectMapper().valueToTree(getLineOrBarPlay(lineText,"line")));
//        charts.setBar(new ObjectMapper().valueToTree(getLineOrBarPlay(barText,"bar")));
//        charts.setPie(null);
//        return super.save(charts);
//    }

    public boolean refresh(RefreshDTO dto){
        List<Integer> ids = dto.getUserSelect();
        Charts charts = new Charts();
        charts.setLine(new ObjectMapper().valueToTree(getLineOrBar(dto.getLineText(),"line",ids)));
        charts.setBar(new ObjectMapper().valueToTree(getLineOrBar(dto.getBarText(), "bar",ids)));
        charts.setPie(new ObjectMapper().valueToTree(getSeriesPie()));
        return super.save(charts);
    }

    public Charts findByLast(){
        QueryWrapper<Charts> wrapper = new QueryWrapper<>();
        wrapper.orderByDesc("id").last("limit 1");
        return chartsMapper.selectOne(wrapper);
    }

    private ChartsDTO getLineOrBar(String text, String type, List<Integer> ids){
        ChartsDTO chartsDTO = new ChartsDTO();
        chartsDTO.setText(text);
        chartsDTO.setWeek(LinsUtil.recentDates(7,"MM-dd"));
        chartsDTO.setSeries(getSeriesLine(type,LinsUtil.recentDates(7,"yyyy-MM-dd"),ids));
        return chartsDTO;
    }

    private List<PieSeriesDTO> getSeriesPie(){
        //构建返回值
        List<PieSeriesDTO> res = new LinkedList<>();
        PieSeriesDTO seriesDTO = new PieSeriesDTO();
        seriesDTO.setName("所有用户");
        seriesDTO.setType("pie");
        seriesDTO.setRadius("50%");
        seriesDTO.setCenter(Arrays.asList("50%","60%"));
        List<ValueAndNameDTO> data = new LinkedList<>();

        List<LogOperationDTO> list = chartsMapper.getLogOperationLast7DaysByAllUser();
        for (LogOperationDTO dto : list) {
            data.add(DTOConverter.convertToValueAndNameDTO(dto));
        }
//        list.forEach(d -> data.add(DTOConverter.convertToValueAndNameDTO(d)));
        seriesDTO.setData(data);
        res.add(seriesDTO);
        return res;
    }

    private List<SeriesDTO> getSeriesLine(String type,List<String> last7days,List<Integer> ids){
        //构建返回值
        List<SeriesDTO> res = new LinkedList<>();
        User user; //防止创建多个对象，取完数据就被替换
        //uid为空表示前端未选择，则填入所有用户的数据
        if (null == ids || ids.size() == 0){
            SeriesDTO seriesDTO = new SeriesDTO();
            seriesDTO.setType(type);
            seriesDTO.setName("所有用户");
            //要放入7个元素
            seriesDTO.setData(makeup7dayData(last7days, chartsMapper.getLogSummaryLast7DaysByAllUser()));
            res.add(seriesDTO);
        }else {
            for (Integer uid : ids) {
                SeriesDTO seriesDTO = new SeriesDTO();
                user = userMapper.selectById(uid);
                seriesDTO.setName(user.getName()); //用户名
                seriesDTO.setType(type);
                seriesDTO.setSmooth(true);
                //要放入7个元素
                seriesDTO.setData(makeup7dayData(last7days, chartsMapper.getLogSummaryLast7DaysByUid(uid)));
                res.add(seriesDTO);
            }
        }
        return res;
    }

    /**
     * 填充最近7天数据
     * @param last7days
     * @param logData
     * @return
     */
    private List<Integer> makeup7dayData(List<String> last7days,List<LogSummaryDTO> logData){
        List<Integer> res = new LinkedList<>();
//        for (String day : last7days) {
//            for (LogSummaryDTO summaryDTO : logData) {
//                //判断是否同一天，注意用==对比的地址值，地址肯定不同
//                if (DateUtil.parse(day).equals(summaryDTO.getLogDate())){
//                    dataList.add(summaryDTO.getNum());
//                }else {
//                    dataList.add(0); //当天没有数据补入0
//                }
//            }
//        }

        Map<Date, Integer> logDataMap = new HashMap<>(); // 用于快速查找对应日期的数据
        // 首先，将logData中的数据按日期组织起来
        for (LogSummaryDTO summaryDTO : logData) {
            logDataMap.put(summaryDTO.getLogDate(), summaryDTO.getNum());
        }
        // 然后，遍历last7days，并根据日期从logDataMap中获取数据
        for (String day : last7days) {
            Integer num = logDataMap.getOrDefault(DateUtil.parse(day), 0); // 如果找不到日期，则返回0
            res.add(num);
        }
        return res;
    }

}
